package models

import "errors"

// PromptMessage represents a single conversational turn sent to the LLM.
type PromptMessage struct {
	Role    string `json:"role" binding:"required"`
	Content string `json:"content" binding:"required"`
}

// PromptCompletionRequest is the payload accepted by POST /api/prompt.
type PromptCompletionRequest struct {
	ProjectID   string          `json:"projectId"`
	PageID      string          `json:"pageId"`
	VersionID   string          `json:"versionId"`
	Prompt      string          `json:"prompt"`
	Messages    []PromptMessage `json:"messages"`
	Model       string          `json:"model"`
	Temperature *float32        `json:"temperature"`
	MaxTokens   *int            `json:"maxTokens"`
	TopP        *float32        `json:"topP"`
}

// PromptCompletionInput is the normalized request passed to the service layer.
type PromptCompletionInput struct {
	ProjectID   string
	PageID      string
	VersionID   string
	Model       string
	Messages    []PromptMessage
	Temperature *float32
	MaxTokens   *int
	TopP        *float32
}

const (
	// PromptStreamChunkTypeToken represents a new delta token from the LLM.
	PromptStreamChunkTypeToken = "token"
	// PromptStreamChunkTypeRole represents a role change event.
	PromptStreamChunkTypeRole = "role"
	// PromptStreamChunkTypeDone indicates streaming has finished successfully.
	PromptStreamChunkTypeDone = "done"
	// PromptStreamChunkTypeError indicates the stream terminated with an error.
	PromptStreamChunkTypeError = "error"
)

// PromptStreamChunk is the structure emitted over the SSE stream to clients.
type PromptStreamChunk struct {
	Type  string `json:"type"`
	Data  string `json:"data,omitempty"`
	Error string `json:"error,omitempty"`
}

// NormalizePromptMessages ensures that at least one message is available,
// falling back to the raw prompt text if provided.
func NormalizePromptMessages(req PromptCompletionRequest) ([]PromptMessage, error) {
	messages := append([]PromptMessage{}, req.Messages...)

	if len(messages) == 0 && req.Prompt != "" {
		messages = append(messages, PromptMessage{
			Role:    "user",
			Content: req.Prompt,
		})
	}

	if len(messages) == 0 {
		return nil, errors.New("either prompt or messages must be provided")
	}

	return messages, nil
}
